const puppeteer = require('puppeteer-core');
const { ipcMain } = require('electron');
const fetch = require('node-fetch');
const { exec } = require('child_process');
const os = require('os');

/**
 * 消息服务类，负责处理浏览器连接和消息监控
 */
class MessageService {
    constructor() {
        this.browser = null;
        this.page = null;
        this.isStarting = false;
        this.isMonitoring = false;
        this.isBrowserReady = false;
        this.messageHistory = new Set();
        this.retryCount = 0;
        this.maxRetries = 10;
        this.replyConfig = null;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 3;
        this.lastProcessedTime = 0;
        this.processInterval = 2000; // 处理消息的最小时间间隔（毫秒）
        this.mainWindow = null; // 添加 mainWindow 属性
        this._isProcessingMessages = false;
    }

    /**
     * 设置主窗口
     * @param {BrowserWindow} window - Electron 主窗口实例
     */
    setMainWindow(window) {
        this.mainWindow = window;
    }

    /**
     * 发送日志消息
     * @param {string} message - 日志消息
     * @param {string} [type='info'] - 日志类型
     */
    sendLog(message, type = 'info') {
        if (this.mainWindow) {
            this.mainWindow.webContents.send('log-message', message, type);
        }
    }

    /**
     * 更新状态
     * @param {boolean} ready - 浏览器是否就绪
     * @private
     */
    _updateStatus(ready) {
        this.isBrowserReady = ready;
        this.sendLog(ready ? '浏览器已就绪' : '浏览器未就绪', ready ? 'success' : 'warning');
        if (this.mainWindow) {
            this.mainWindow.webContents.send('browser-ready', ready);
            this.mainWindow.webContents.send('status-update', this.isMonitoring);
        }
    }

    /**
     * 清理状态和资源
     * @private
     */
    _cleanup() {
        if (this.page) {
            this.page.removeAllListeners('error');
        }
        if (this.browser) {
            this.browser.removeAllListeners('disconnected');
        }
        this.browser = null;
        this.page = null;
        this.isStarting = false;
        this.isMonitoring = false;
        this.isBrowserReady = false;
        this.reconnectAttempts = 0;
        this.retryCount = 0;
        this.lastProcessedTime = 0;
    }

    /**
     * 检查是否可以处理新消息
     * @returns {boolean}
     * @private
     */
    _canProcessMessage() {
        const now = Date.now();
        if (now - this.lastProcessedTime < this.processInterval) {
            return false;
        }
        this.lastProcessedTime = now;
        return true;
    }

    /**
     * 尝试重新连接浏览器
     * @returns {Promise<boolean>}
     * @private
     */
    async _reconnectBrowser() {
        if (this.reconnectAttempts >= this.maxReconnectAttempts) {
            this.sendLog('重连次数过多，请手动重启浏览器', 'error');
            return false;
        }

        this.reconnectAttempts++;
        this.sendLog(`尝试重新连接浏览器 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`, 'info');

        try {
            await this.startBrowser();
            this.reconnectAttempts = 0;
            return true;
        } catch (error) {
            this.sendLog(`重新连接失败: ${error.message}`, 'error');
            return false;
        }
    }

    /**
     * 等待页面加载完成
     * @returns {Promise<void>}
     * @private
     */
    async _waitForPageLoad() {
        try {
            // 等待页面加载完成，不设置超时
            await this.page.waitForNavigation({ waitUntil: 'networkidle0' });
            this.sendLog('浏览器已就绪', 'success');
            
            // 等待消息入口元素出现，不设置超时
            await this.page.waitForSelector('#new-im-entrance', { 
                visible: true 
            });
            this.sendLog('消息入口已就绪', 'success');
            
            // 检查消息入口是否可点击
            const isClickable = await this.page.evaluate(() => {
                const element = document.querySelector('#new-im-entrance');
                if (!element) return false;
                
                const style = window.getComputedStyle(element);
                return style.display !== 'none' && 
                       style.visibility !== 'hidden' && 
                       style.opacity !== '0' &&
                       !element.disabled &&
                       element.offsetParent !== null;
            });
            
            if (!isClickable) {
                throw new Error('消息入口不可点击');
            }

            // 尝试点击消息入口
            await this.page.click('#new-im-entrance');
            this.sendLog('已点击消息入口', 'success');

            // 等待消息列表加载，不设置超时
            await this.page.waitForSelector('.scroll-list-view-container', {
                visible: true
            });
            
            // 页面加载完成，更新状态
            this.isBrowserReady = true;
            this.isStarting = false;
            
            // 通知渲染进程页面已就绪
            this.sendLog('页面准备就绪，可以开始监控', 'success');
            if (this.mainWindow) {
                this.mainWindow.webContents.send('browser-ready', true);
            }
            
        } catch (error) {
            this.sendLog(`等待页面加载失败: ${error.message}`, 'error');
            this.isBrowserReady = false;
            this.isStarting = false;
            if (this.mainWindow) {
                this.mainWindow.webContents.send('browser-ready', false);
            }
            throw error;
        }
    }

    /**
     * 启动浏览器
     * @returns {Promise<void>}
     */
    async startBrowser() {
        if (this.isStarting) {
            this.sendLog('浏览器正在启动中，请稍候...', 'info');
            return;
        }

        this.isStarting = true;
        this.isBrowserReady = false;
        this.sendLog('正在启动浏览器...', 'info');

        try {
            // 连接到已启动的浏览器
            const browserURL = 'http://127.0.0.1:9222';
            this.browser = await puppeteer.connect({
                browserURL,
                defaultViewport: null
            });

            // 获取所有页面
            const pages = await this.browser.pages();
            this.page = pages[0] || await this.browser.newPage();

            // 移除页面超时设置
            this.page.setDefaultNavigationTimeout(0);
            this.page.setDefaultTimeout(0);

            // 监听页面错误
            this.page.on('error', (error) => {
                this.sendLog(`页面错误: ${error.message}`, 'error');
                this.isBrowserReady = false;
                if (this.mainWindow) {
                    this.mainWindow.webContents.send('browser-ready', false);
                }
            });

            // 监听浏览器断开连接
            this.browser.on('disconnected', () => {
                this.sendLog('浏览器连接已断开', 'error');
                this._cleanup();
                this.isBrowserReady = false;
                if (this.mainWindow) {
                    this.mainWindow.webContents.send('browser-ready', false);
                }
            });

            // 等待页面加载完成
            await this._waitForPageLoad();

        } catch (error) {
            this.sendLog(`启动浏览器失败: ${error.message}`, 'error');
            this._cleanup();
            this.isBrowserReady = false;
            this.isStarting = false;
            if (this.mainWindow) {
                this.mainWindow.webContents.send('browser-ready', false);
            }
            throw error;
        }
    }

    /**
     * 获取AI回复
     * @param {string} message - 用户消息
     * @returns {Promise<string>} - AI回复
     */
    async getAIResponse(message) {
        try {
            // 从主进程获取回复配置
            if (!this.replyConfig) {
                this.replyConfig = await new Promise((resolve) => {
                    const handler = (event, config) => {
                        ipcMain.removeListener('reply-config', handler);
                        resolve(config);
                    };
                    ipcMain.on('reply-config', handler);
                    ipcMain.emit('get-reply-config');
                });
            }

            if (!this.replyConfig || !this.replyConfig.keywords || !this.replyConfig.defaultReplies) {
                throw new Error('回复配置无效');
            }

            // 检查关键词匹配
            for (const [keyword, reply] of Object.entries(this.replyConfig.keywords)) {
                if (message.includes(keyword)) {
                    this.sendLog(`收到消息: ${message}`, 'info');
                    this.sendLog(`匹配到关键词: ${keyword}`, 'info');
                    this.sendLog(`准备回复: ${reply}`, 'info');
                    return reply;
                }
            }

            // 如果没有匹配的关键词，从默认回复中随机选择
            if (this.replyConfig.defaultReplies.length === 0) {
                this.sendLog('没有可用的默认回复', 'warning');
                return '抱歉，稍等下～';
            }

            const randomIndex = Math.floor(Math.random() * this.replyConfig.defaultReplies.length);
            const reply = this.replyConfig.defaultReplies[randomIndex];
            this.sendLog(`收到消息: ${message}`, 'info');
            this.sendLog(`未匹配到关键词，使用默认回复: ${reply}`, 'info');
            return reply;
        } catch (error) {
            this.sendLog(`获取AI回复失败: ${error.message}`, 'error');
            const defaultReply = '抱歉，稍等下～';
            this.sendLog(`使用默认回复: ${defaultReply}`, 'warning');
            return defaultReply;
        }
    }

    /**
     * 发送回复
     * @param {string} reply - 回复内容
     * @returns {Promise<void>}
     */
    async sendReply(reply) {
        try {
            // 等待输入框出现并确保可以输入
            await this.page.waitForSelector('.textarea', { 
                visible: true,
                timeout: 5000 
            });

            // 清空输入框
            await this.page.evaluate(() => {
                const textarea = document.querySelector('.textarea');
                if (textarea) {
                    textarea.innerHTML = '';
                    textarea.value = '';
                }
            });
            
            // 输入回复内容
            await this.page.type('.textarea', reply, { delay: 50 });
            
            // 等待发送按钮可用
            await this.page.waitForFunction(() => {
                const button = document.querySelector('.boo-btn-primary');
                return button && !button.disabled && button.offsetParent !== null;
            }, { 
                timeout: 5000,
                polling: 100
            });
            
            // 点击发送按钮
            await this.page.click('.boo-btn-primary');
            
            // 等待发送完成（按钮变为禁用状态）
            await this.page.waitForFunction(() => {
                const button = document.querySelector('.boo-btn-primary');
                return !button || button.disabled;
            }, { 
                timeout: 5000,
                polling: 100
            });

            // 等待消息发送动画完成
            await new Promise(resolve => setTimeout(resolve, 1000));
            
            // 检查是否真的发送成功
            const sendSuccess = await this.page.evaluate(() => {
                const errorTip = document.querySelector('.error-tip');
                return !errorTip || !errorTip.offsetParent;
            });

            if (!sendSuccess) {
                throw new Error('消息发送失败，请检查网络连接');
            }

            this.sendLog(`已发送回复: ${reply}`, 'success');
        } catch (error) {
            this.sendLog(`发送回复失败: ${error.message}`, 'error');
            throw error; // 向上传递错误，让调用者处理
        }
    }

    /**
     * 检查页面状态
     * @returns {Promise<boolean>}
     * @private
     */
    async _checkPageStatus() {
        try {
            if (!this.page) {
                throw new Error('页面未初始化');
            }

            // 检查页面是否仍然可用
            await this.page.evaluate(() => document.readyState);

            // 检查消息列表是否存在
            const listExists = await this.page.evaluate(() => {
                const container = document.querySelector('.scroll-list-view-container');
                return container && container.offsetParent !== null;
            });

            if (!listExists) {
                throw new Error('消息列表不可见，可能需要重新登录');
            }

            return true;
        } catch (error) {
            this.sendLog(`页面状态检查失败: ${error.message}`, 'error');
            return false;
        }
    }

    /**
     * 检查新消息
     * @returns {Promise<void>}
     * @private
     */
    async _checkNewMessages() {
        if (this._isProcessingMessages) {
            return;
        }

        try {
            this._isProcessingMessages = true;

            // 检查页面状态
            const pageOk = await this._checkPageStatus();
            if (!pageOk) {
                throw new Error('页面状态异常');
            }

            // 检查处理间隔
            if (!this._canProcessMessage()) {
                this._isProcessingMessages = false;
                return;
            }

            const result = await this.page.evaluate(() => {
                const messages = [];
                const logs = [];

                try {
                    const container = document.querySelector('.scroll-list-view-container');
                    if (!container || !container.offsetParent) {
                        throw new Error('消息列表容器不可见');
                    }
                    
                    const messageListEl = container.querySelector('.scroll-list-view-list');
                    if (!messageListEl) {
                        return { messages, logs: [] };
                    }

                    const items = messageListEl.querySelectorAll('.scroll-list-item');
                    if (!items || items.length === 0) {
                        return { messages, logs: [] };
                    }

                    // 获取所有未处理的消息
                    const processItems = Array.from(items);
                    if (processItems.length > 0) {
                        logs.push(`发现 ${processItems.length} 条新消息`);
                    }

                    processItems.forEach(item => {
                        try {
                            if (!item.offsetParent || item.disabled) {
                                return;
                            }

                            const messageData = {
                                id: item.getAttribute('data-id'),
                                name: '',
                                time: '',
                                content: '',
                                countdown: null,
                                clickable: false
                            };

                            if (!messageData.id) {
                                return;
                            }

                            const userNameEl = item.querySelector('.user-name');
                            messageData.name = userNameEl ? userNameEl.textContent.trim() : '';
                            
                            const timeEl = item.querySelector('.session-time');
                            messageData.time = timeEl ? timeEl.textContent.trim() : '';
                            
                            const previewEl = item.querySelector('.im-session-preview span:not(.c-red)');
                            if (previewEl) {
                                messageData.content = previewEl.textContent.trim();
                                const countDownEl = previewEl.querySelector('.count-down');
                                messageData.countdown = countDownEl ? countDownEl.textContent.trim() : null;
                            }

                            messageData.clickable = item.offsetParent !== null && !item.disabled;

                            if (messageData.content) {
                                messages.push(messageData);
                                logs.push(`发现新消息: ${messageData.name} - ${messageData.content}`);
                            }
                        } catch (err) {
                            // 移除处理消息项错误的日志
                        }
                    });
                } catch (error) {
                    // 只在出现严重错误时记录日志
                    if (error.message !== '消息列表容器不可见') {
                        logs.push(`获取消息列表时出错: ${error.message}`);
                    }
                }

                return { messages, logs };
            });

            // 只有在有日志时才输出
            if (result.logs && result.logs.length > 0) {
                result.logs.forEach(log => this.sendLog(log));
            }

            if (result.messages && result.messages.length > 0) {
                // 按顺序处理每条消息
                for (const message of result.messages) {
                    if (!this.isMonitoring) break;
                    
                    try {
                        // 检查是否已处理过该消息
                        if (this.messageHistory.has(message.id)) {
                            continue;
                        }

                        // 检查消息是否可点击
                        if (!message.clickable) {
                            this.sendLog('消息项不可点击，跳过', 'info');
                            continue;
                        }

                        this.sendLog(`处理消息: ${message.name} - ${message.content}`, 'info');
                        
                        // 点击消息并等待对话框
                        try {
                            // 再次检查消息元素是否存在且可交互
                            const isClickable = await this.page.evaluate((messageId) => {
                                const element = document.querySelector(`[data-id="${messageId}"]`);
                                if (!element || !element.offsetParent) return false;
                                
                                const style = window.getComputedStyle(element);
                                return style.display !== 'none' && 
                                       style.visibility !== 'hidden' && 
                                       style.opacity !== '0' &&
                                       !element.disabled;
                            }, message.id);

                            if (!isClickable) {
                                this.sendLog(`消息 ${message.id} 不可点击，可能已被处理，跳过`, 'info');
                                this.messageHistory.add(message.id);
                                continue;
                            }

                            // 使用 evaluate 直接在页面上下文中点击元素
                            await this.page.evaluate((messageId) => {
                                const element = document.querySelector(`[data-id="${messageId}"]`);
                                if (element) {
                                    element.click();
                                    return true;
                                }
                                return false;
                            }, message.id);

                            // 等待对话框出现
                            try {
                                await this.page.waitForFunction(() => {
                                    const textarea = document.querySelector('.textarea');
                                    return textarea && textarea.offsetParent !== null;
                                }, { 
                                    timeout: 10000,
                                    polling: 100
                                });
                            } catch (timeoutError) {
                                // 如果超时，检查是否真的没有出现输入框
                                const textareaExists = await this.page.evaluate(() => {
                                    const textarea = document.querySelector('.textarea');
                                    return textarea && textarea.offsetParent !== null;
                                });

                                if (!textareaExists) {
                                    this.sendLog(`消息 ${message.id} 对话框加载超时，跳过处理`, 'warning');
                                    this.messageHistory.add(message.id);
                                    continue;
                                }
                            }

                            // 再次检查消息是否仍然存在
                            const stillExists = await this.page.evaluate((messageId) => {
                                const element = document.querySelector(`[data-id="${messageId}"]`);
                                return element && element.offsetParent !== null;
                            }, message.id);

                            if (!stillExists) {
                                this.sendLog(`消息 ${message.id} 已不存在，跳过处理`, 'info');
                                this.messageHistory.add(message.id);
                                continue;
                            }

                            // 获取并发送回复
                            const reply = await this.getAIResponse(message.content);
                            await this.sendReply(reply);
                            
                            // 记录已处理的消息
                            this.messageHistory.add(message.id);
                            
                            // 等待一段时间再处理下一条
                            await new Promise(resolve => setTimeout(resolve, 2000));

                        } catch (error) {
                            // 处理各种可能的错误
                            if (error.message.includes('Node is detached from document') ||
                                error.message.includes('No element found for selector')) {
                                this.sendLog(`消息 ${message.id} 已不可用，跳过处理`, 'info');
                                this.messageHistory.add(message.id);
                                continue;
                            }
                            // 其他错误
                            this.sendLog(`处理消息失败: ${error.message}`, 'error');
                            // 如果是致命错误，添加到历史记录避免重复处理
                            if (error.message.includes('页面未加载') || 
                                error.message.includes('连接已断开')) {
                                this.messageHistory.add(message.id);
                            }
                        }
                    } catch (error) {
                        // 如果是元素不存在的错误，直接跳过并记录
                        if (error.message.includes('No element found for selector')) {
                            this.sendLog(`消息 ${message.id} 已不存在，跳过处理`, 'info');
                            this.messageHistory.add(message.id);
                            continue;
                        }
                        this.sendLog(`处理消息失败: ${error.message}`, 'error');
                    }
                }
            }
        } catch (error) {
            this.sendLog(`检查消息时出错: ${error.message}`, 'error');
            throw error;
        } finally {
            this._isProcessingMessages = false;
        }
    }

    /**
     * 开始监控消息
     * @returns {Promise<void>}
     */
    async monitorMessages() {
        if (!this.isBrowserReady) {
            this.sendLog('浏览器未就绪，无法开始监控', 'error');
            throw new Error('浏览器未就绪');
        }

        if (this.isMonitoring) {
            this.sendLog('监控已经在运行中', 'warning');
            return;
        }

        try {
            this.isMonitoring = true;
            this.sendLog('开始监控消息...', 'info');

            // 确保页面已加载
            if (!this.page) {
                throw new Error('页面未加载');
            }

            // 检查消息列表是否存在
            const messageListExists = await this.page.evaluate(() => {
                return !!document.querySelector('.scroll-list-view-container');
            });

            if (!messageListExists) {
                throw new Error('消息列表未找到');
            }

            // 开始监控消息
            this._startMessagePolling();
            this.sendLog('消息监控已启动', 'success');

        } catch (error) {
            this.isMonitoring = false;
            this.sendLog(`启动监控失败: ${error.message}`, 'error');
            throw error;
        }
    }

    /**
     * 停止监控
     * @returns {Promise<void>}
     */
    async stopMonitoring() {
        if (!this.isMonitoring) {
            this.sendLog('监控已经停止', 'warning');
            return;
        }

        try {
            this.isMonitoring = false;
            this.sendLog('停止监控消息', 'info');
            
            // 清理定时器
            if (this._messageCheckInterval) {
                clearInterval(this._messageCheckInterval);
                this._messageCheckInterval = null;
            }

            this.sendLog('监控已停止', 'success');
        } catch (error) {
            this.sendLog(`停止监控失败: ${error.message}`, 'error');
            throw error;
        }
    }

    /**
     * 开始轮询消息
     * @private
     */
    _startMessagePolling() {
        // 清理已有的定时器
        if (this._messageCheckInterval) {
            clearInterval(this._messageCheckInterval);
        }

        // 设置新的定时器
        this._messageCheckInterval = setInterval(async () => {
            if (!this.isMonitoring) {
                clearInterval(this._messageCheckInterval);
                return;
            }

            try {
                // 检查是否正在处理消息
                if (this._isProcessingMessages) {
                    return;
                }
                await this._checkNewMessages();
            } catch (error) {
                this.sendLog(`检查消息时出错: ${error.message}`, 'error');
                // 如果是致命错误，停止监控
                if (error.message.includes('页面未加载') || error.message.includes('消息列表未找到')) {
                    this.stopMonitoring();
                }
            }
        }, 2000); // 每2秒检查一次
    }

    async waitForBrowserReady(maxRetries = 10, retryInterval = 1000) {
        let retries = 0;
        while (retries < maxRetries) {
            try {
                if (!this.browser) {
                    this.browser = await puppeteer.connect({
                        browserURL: 'http://127.0.0.1:9222',
                        defaultViewport: null
                    });
                }

                const pages = await this.browser.pages();
                this.page = pages[0];
                
                // 等待页面加载完成
                await this.page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 5000 }).catch(() => {});
                
                // 检查是否可以访问必要的元素
                await this.page.waitForSelector('#root', { timeout: 5000 });
                
                return true;
            } catch (error) {
                retries++;
                if (retries >= maxRetries) {
                    throw new Error('浏览器连接超时，请确保浏览器已正确启动');
                }
                await new Promise(resolve => setTimeout(resolve, retryInterval));
            }
        }
        return false;
    }
}

module.exports = MessageService; 